<!DOCTYPE html>
<html lang="en-US" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>暗黑模式前端修改方案 | 秋殇の博客</title>
    <meta name="description" content="之前我们做过公有云换肤方案，有长沙、乌鲁木齐几种主题包，使用的是样式变量的方式，可以支持在线动态换肤。结合这次暗黑模式的需求，综合考虑适用性、改动量，沿用这种方案，新增dark主题，做了些代码改造">
    <link rel="preload stylesheet" href="/assets/style.a6a6cd3c.css" as="style">
    <link rel="modulepreload" href="/assets/chunks/VPAlgoliaSearchBox.a18b445d.js">
    <link rel="modulepreload" href="/assets/app.4866b9fc.js">
    <link rel="modulepreload" href="/assets/pages_javascript_暗黑模式前端修改方案.md.6cdec8ec.lean.js">
    
    <link rel="icon" href="/images/fish.jpg">
  <link rel="manifest" href="/manifest.json">
  <meta name="theme-color" content="#235dc8">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <link rel="apple-touch-icon" href="/images/fish.jpg">
  <link rel="mask-icon" href="/images/fish.jpg" color="#235dc8">
  <meta name="msapplication-TileImage" content="/images/fish.jpg">
  <meta name="msapplication-TileColor" content="#000000">
  <script>var _hmt=_hmt||[];(function(){var e=document.createElement("script");e.src="https://hm.baidu.com/hm.js?f00a6211b690ac3505105511f6b90b30";var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)})();</script>
  <script id="check-dark-light">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
  </head>
  <body>
    <div id="app"><div class="Layout" data-v-bcf58b99><!--[--><!--]--><!--[--><span tabindex="-1" data-v-c25b702d></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-c25b702d> Skip to content </a><!--]--><!----><header class="VPNav no-sidebar" data-v-bcf58b99 data-v-e7025237><div class="VPNavBar" data-v-e7025237 data-v-4882c5cb><div class="container" data-v-4882c5cb><div class="title" data-v-4882c5cb><div class="VPNavBarTitle" data-v-4882c5cb data-v-c9f092c8><a class="title" href="/" data-v-c9f092c8><!--[--><!--]--><!--[--><img class="VPImage logo" src="/images/fish.jpg" alt data-v-261838bf><!--]--><!--[-->秋殇の博客<!--]--><!--[--><!--]--></a></div></div><div class="content" data-v-4882c5cb><div class="curtain" data-v-4882c5cb></div><!--[--><!--]--><div class="VPNavBarSearch search" data-v-4882c5cb style="--d3726eb8:&#39;Meta&#39;;"><div id="docsearch"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg class="DocSearch-Search-Icon" width="20" height="20" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-4882c5cb data-v-11c85cf4><span id="main-nav-aria-label" class="visually-hidden" data-v-11c85cf4>Main Navigation</span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/" data-v-11c85cf4 data-v-bbaa7ea4 data-v-7fdf1e32><!--[-->首页<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/pages/list/" data-v-11c85cf4 data-v-bbaa7ea4 data-v-7fdf1e32><!--[-->文章<!--]--><!----></a><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-11c85cf4 data-v-e54c5eb4><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-e54c5eb4><span class="text" data-v-e54c5eb4><!----> 分类 <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-e54c5eb4><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-e54c5eb4><div class="VPMenu" data-v-e54c5eb4 data-v-d9758112><div class="items" data-v-d9758112><!--[--><!--[--><div class="VPMenuLink" data-v-d9758112 data-v-80fb0ac9><a class="VPLink link" href="/pages/vue/code.html" data-v-80fb0ac9 data-v-7fdf1e32><!--[-->vue<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-d9758112 data-v-80fb0ac9><a class="VPLink link" href="/pages/javascript/code.html" data-v-80fb0ac9 data-v-7fdf1e32><!--[-->javascript<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-d9758112 data-v-80fb0ac9><a class="VPLink link" href="/pages/react/code.html" data-v-80fb0ac9 data-v-7fdf1e32><!--[-->react<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-d9758112 data-v-80fb0ac9><a class="VPLink link" href="/pages/react-native/code.html" data-v-80fb0ac9 data-v-7fdf1e32><!--[-->react-native<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-d9758112 data-v-80fb0ac9><a class="VPLink link" href="/pages/python/code.html" data-v-80fb0ac9 data-v-7fdf1e32><!--[-->python<!--]--><!----></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/pages/logs/" data-v-11c85cf4 data-v-bbaa7ea4 data-v-7fdf1e32><!--[-->日志<!--]--><!----></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-4882c5cb data-v-8af7bd39><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-label="toggle dark mode" aria-checked="false" data-v-8af7bd39 data-v-cfd5b55f data-v-3532bfcd><span class="check" data-v-3532bfcd><span class="icon" data-v-3532bfcd><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-cfd5b55f><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-cfd5b55f><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-4882c5cb data-v-1043976d data-v-d6312b01><!--[--><a class="VPSocialLink" href="https://github.com/bayi-95/" target="_blank" rel="noopener" data-v-d6312b01 data-v-e02d7003><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-4882c5cb data-v-441d75c0 data-v-e54c5eb4><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-e54c5eb4><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-e54c5eb4><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle><circle cx="5" cy="12" r="2"></circle></svg></button><div class="menu" data-v-e54c5eb4><div class="VPMenu" data-v-e54c5eb4 data-v-d9758112><!----><!--[--><!--[--><!----><div class="group" data-v-441d75c0><div class="item appearance" data-v-441d75c0><p class="label" data-v-441d75c0>Appearance</p><div class="appearance-action" data-v-441d75c0><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-label="toggle dark mode" aria-checked="false" data-v-441d75c0 data-v-cfd5b55f data-v-3532bfcd><span class="check" data-v-3532bfcd><span class="icon" data-v-3532bfcd><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-cfd5b55f><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-cfd5b55f><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div></div></div><div class="group" data-v-441d75c0><div class="item social-links" data-v-441d75c0><div class="VPSocialLinks social-links-list" data-v-441d75c0 data-v-d6312b01><!--[--><a class="VPSocialLink" href="https://github.com/bayi-95/" target="_blank" rel="noopener" data-v-d6312b01 data-v-e02d7003><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-4882c5cb data-v-33db8862><span class="container" data-v-33db8862><span class="top" data-v-33db8862></span><span class="middle" data-v-33db8862></span><span class="bottom" data-v-33db8862></span></span></button></div></div></div><!----></header><!----><!----><div class="VPContent" id="VPContent" data-v-bcf58b99 data-v-d068f002><div class="VPDoc has-aside" data-v-d068f002 data-v-2715c46c><div class="container" data-v-2715c46c><div class="aside" data-v-2715c46c><div class="aside-curtain" data-v-2715c46c></div><div class="aside-container" data-v-2715c46c><div class="aside-content" data-v-2715c46c><div class="VPDocAside" data-v-2715c46c data-v-62f1dbe3><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" data-v-62f1dbe3 data-v-7a7145f2><div class="content" data-v-7a7145f2><div class="outline-marker" data-v-7a7145f2></div><div class="outline-title" data-v-7a7145f2>On this page</div><nav aria-labelledby="doc-outline-aria-label" data-v-7a7145f2><span class="visually-hidden" id="doc-outline-aria-label" data-v-7a7145f2> Table of Contents for current page </span><ul class="root" data-v-7a7145f2 data-v-f3203836><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-62f1dbe3></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-2715c46c><div class="content-container" data-v-2715c46c><!--[--><!--]--><main class="main" data-v-2715c46c><div style="position:relative;" class="vp-doc _pages_javascript_%E6%9A%97%E9%BB%91%E6%A8%A1%E5%BC%8F%E5%89%8D%E7%AB%AF%E4%BF%AE%E6%94%B9%E6%96%B9%E6%A1%88" data-v-2715c46c><div><h1 id="暗黑模式前端修改方案" tabindex="-1">暗黑模式前端修改方案 <a class="header-anchor" href="#暗黑模式前端修改方案" aria-hidden="true">#</a></h1><h2 id="_1-背景" tabindex="-1">1. 背景 <a class="header-anchor" href="#_1-背景" aria-hidden="true">#</a></h2><p>之前我们做过公有云换肤方案，有长沙、乌鲁木齐几种主题包，使用的是样式变量的方式，可以支持在线动态换肤。结合这次暗黑模式的需求，综合考虑适用性、改动量，沿用这种方案，新增 dark 主题，做了些代码改造。</p><h2 id="_2-改造思路" tabindex="-1">2. 改造思路 <a class="header-anchor" href="#_2-改造思路" aria-hidden="true">#</a></h2><h4 id="_2-1-跟随系统" tabindex="-1">2.1 跟随系统 <a class="header-anchor" href="#_2-1-跟随系统" aria-hidden="true">#</a></h4><p>通过 window.matchMedia(&#39;(prefers-color-scheme: dark)&#39;).matches 可以判断系统是否是暗黑模式，加监听，改变时判断重置主题。</p><h4 id="_2-2-客户端注入" tabindex="-1">2.2 客户端注入 <a class="header-anchor" href="#_2-2-客户端注入" aria-hidden="true">#</a></h4><p>客户端注入，可以通过<code>window.SnColorTheme</code>获取。如果注入不及时，可以加监听来设置：</p><div class="language-javascript"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki material-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 监听客户端抛出的主题变动事件</span></span>
<span class="line"><span style="color:#A6ACCD;">document</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addEventListener</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">SnThemeChange</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">	</span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">snColorTheme</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">window</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">SnColorTheme</span></span>
<span class="line"><span style="color:#F07178;">	</span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">themeName</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;&#39;</span></span>
<span class="line"><span style="color:#F07178;">	</span><span style="color:#89DDFF;font-style:italic;">switch</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">snColorTheme</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">		</span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">light</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#F07178;">			</span><span style="color:#A6ACCD;">themeName</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">Light</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"><span style="color:#F07178;">			</span><span style="color:#89DDFF;font-style:italic;">break</span></span>
<span class="line"><span style="color:#F07178;">		</span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">dark</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#F07178;">			</span><span style="color:#A6ACCD;">themeName</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">Dark</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"><span style="color:#F07178;">			</span><span style="color:#89DDFF;font-style:italic;">break</span></span>
<span class="line"><span style="color:#F07178;">	</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">	</span><span style="color:#A6ACCD;">themeName</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#82AAFF;">setTheme</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">themeName</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">res</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span></code></pre></div><h4 id="_2-3-图片静态资源处理" tabindex="-1">2.3 图片静态资源处理 <a class="header-anchor" href="#_2-3-图片静态资源处理" aria-hidden="true">#</a></h4><p>图片文件根据引入类型做不同处理（应该大部分不用变，只个别图需要）：</p><p>1）背景图方式</p><p>图片文件，通过背景图方式引入，在对应主题包下的 img 文件夹放图片资源。</p><ol><li><p>可以通过样式覆盖背景图</p></li><li><p>也可以把图片地址当作变量提出来</p></li><li><p>推荐第二种，需准备多套图</p></li></ol><p>PS: 把图片亮度变暗，可以使用以下方式：</p><div class="language-css"><button title="Copy Code" class="copy"></button><span class="lang">css</span><pre class="shiki material-palenight"><code><span class="line"><span style="color:#A6ACCD;">// 方法1: 会使背景色上面的元素变化</span></span>
<span class="line"><span style="color:#FFCB6B;">filter</span><span style="color:#A6ACCD;">: brightness(80%); // 设置图片的亮度，使其看起来更亮或更暗</span></span>
<span class="line"><span style="color:#A6ACCD;">opacity: 0.9;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">// 方法2: 有些渐变色的图，如果用这种方法，边界会明显些，效果不太好</span></span>
<span class="line"><span style="color:#A6ACCD;">background: linear-gradient(rgba(0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> 0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> 0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> 0</span><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">4</span><span style="color:#A6ACCD;">), rgba(0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> 0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> 0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> 0</span><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">4</span><span style="color:#A6ACCD;">)),</span></span>
<span class="line"><span style="color:#A6ACCD;">	url(&#39;</span><span style="color:#89DDFF;">~</span><span style="color:#A6ACCD;">assets/img/img_note_topbg.png&#39;) </span><span style="color:#FFCB6B;">no-repeat</span><span style="color:#A6ACCD;"> top left;</span></span>
<span class="line"></span></code></pre></div><p>2）img 引入/require 引入</p><p>在对应 theme 下 img 目录放对应的图片资源，写一个方法，处理传入的图片地址，返回在当前主题下静态资源地址，例如：</p><ol><li><p>引入依赖，页面混入<code>ThemeMixin</code></p><div class="language-javascript"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki material-palenight"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> ThemeMixin </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">themes/utils/mixin</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">getThemeImg</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">themes/utils</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"></span></code></pre></div></li><li><p>使用<code>getThemeImg</code>处理图片，注意要加上<code>key=&quot;themeKey&quot;</code>，这样在线动态切换主题时，会更新图片</p><div class="language-vue"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki material-palenight"><code><span class="line"><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">img</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">src</span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">getThemeImg(</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">require(</span><span style="color:#A6ACCD;">&#39;assets/img/icon_invoice_pdf.png&#39;), &#39;icon_invoice_pdf.png&#39; </span><span style="color:#C792EA;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">}</span></span>
<span class="line"><span style="color:#C792EA;">alt</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">height</span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;">{200}</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">width</span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;">{200}</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">key</span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;">{themeKey}</span><span style="color:#A6ACCD;"> /&gt;</span></span>
<span class="line"></span></code></pre></div><p>tips: 因为不能 require(变量)，所以这里直接传入了。</p></li></ol><p>3）部分简单的图可以考虑直接图片反色处理（如果 UI 同意）</p><p><code>filter: invert(100%)</code>，黑的变白的，需要反色的图加全局 class 类名。</p><p>4）复杂的 svg（图形组合）</p><ul><li>Color 只能控制一种颜色，如果背景色与图形是两种色值，可以的话，把背景色去掉，让外面容器控制，让 color 修改图形颜色；</li><li>如果不行，考虑两套 svg，根据 window.SINO_THEME 判断控制，混入<code>ThemeMixin</code>在线动态切换主题时，会更新 svg；</li><li>svg 图里的 fill=&#39;&#39; 这里可以使用样式变量；</li></ul><h4 id="_2-4-一些自定义的特殊元素" tabindex="-1">2.4 一些自定义的特殊元素 <a class="header-anchor" href="#_2-4-一些自定义的特殊元素" aria-hidden="true">#</a></h4><p>比如自定义渐变色的按钮，需要根据暗黑效果（问下 ui），在暗黑主题样式文件里<code>style/index.less</code> 写样式覆盖修改。</p><h2 id="_3-修改点" tabindex="-1">3. 修改点 <a class="header-anchor" href="#_3-修改点" aria-hidden="true">#</a></h2><blockquote><p>注意：</p><ol><li>背景色是白色的，改为黑色，定义个变量 <code>@background-white</code>（组件库里的写样式覆盖掉）；文字是白色的不用改</li><li>建议全局搜索，: #，找出项目里没有用样式变量的颜色，做下提取变量处理</li><li>我们目前暗黑的改造是不涉及组件库的，那么遇到组件库里没有用样式变量的地方，如果需要变色那要覆盖修改下样式</li><li>改完后，需要一个个页面看下，有样式不确定的找下 UI</li></ol></blockquote><p>之前有换肤改造的：</p><ol><li><p>把之前的<code>themes</code>移动到项目根目录下</p></li><li><p><code>source</code>里<code>themes</code>下的资源，替换<code>themes</code>下 index.js，删除 themeMap.js、删除其他主题比如：ChangSha、WuLuMuQi，先保留 default，添加 Dark、light 主题、utils 文件夹</p></li><li><p>build 目录下<code>custom-theme.js</code>里面的内容，业务变量对比复制到<code>utils/variables.js</code>文件里，然后这个文件删掉</p></li><li><p>替换<code>webpack.theme.config.js</code></p></li><li><p><code>webpack.base.config.js</code>修改如下：</p></li></ol><img src="/images/dark-1.png" height="400"><ol start="6"><li><p><code>webpack.build.config.js</code>修改：</p><div class="language-javascript"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki material-palenight"><code><span class="line"><span style="color:#89DDFF;">module.exports</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> baseConfig</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">plugins[</span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;">]</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">definitions</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">PRIVATE</span></span>
<span class="line"><span style="color:#A6ACCD;">	</span><span style="color:#89DDFF;">?</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">merge</span><span style="color:#A6ACCD;">(baseConfig</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> prodConfig)</span></span>
<span class="line"><span style="color:#A6ACCD;">	</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">themeConfig</span><span style="color:#A6ACCD;">(</span><span style="color:#82AAFF;">merge</span><span style="color:#A6ACCD;">(baseConfig</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> prodConfig))</span></span>
<span class="line"></span></code></pre></div><p>修改为：</p><div class="language-javascript"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki material-palenight"><code><span class="line"><span style="color:#89DDFF;">module.exports</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">themeConfig</span><span style="color:#A6ACCD;">(</span><span style="color:#82AAFF;">merge</span><span style="color:#A6ACCD;">(baseConfig</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> prodConfig))</span></span>
<span class="line"></span></code></pre></div></li><li><p><s>项目入口文件，Index.html 里面 meta 标签下面加上这段代码： 客户端说不需要加了</s></p><div class="language-html"><button title="Copy Code" class="copy"></button><span class="lang">html</span><pre class="shiki material-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">&lt;!-- &lt;meta name=&quot;color-scheme&quot; content=&quot;dark light&quot;&gt; --&gt;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">&lt;!-- 此meta用于适应暗黑的页面背景，但是weboa禁用暗黑，如果电脑是暗黑模式，刷新页面会由黑闪到白，所以媒体查询使用替代方案 --&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">style</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">type</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">text/css</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">	</span><span style="color:#89DDFF;font-style:italic;">@media</span><span style="color:#A6ACCD;"> screen </span><span style="color:#89DDFF;">and</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#FFCB6B;">max-width</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">767px</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">		</span><span style="color:#89DDFF;">:</span><span style="color:#C792EA;">root</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">			</span><span style="color:#B2CCD6;">color-scheme</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> light dark</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">		</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">	</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">style</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"></span></code></pre></div></li><li><p>项目入口文件，index.js 里面引入<code>ThemeLoader</code>路径修改，之前的删掉：</p><div class="language-javascript"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki material-palenight"><code><span class="line"><span style="color:#89DDFF;">-</span><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> ThemeLoader </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">@/utils/themeLoader</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"><span style="color:#89DDFF;">+</span><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> ThemeLoader </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">themes/utils/loader</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"></span></code></pre></div></li><li><p>之前 commonUtil.js 里 getCssVarValue 方法移到了 themes/utils/index.js 里，可以删掉了，引入方式修改：</p><div class="language-javascript"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki material-palenight"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">getCssVarValue</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">themes/utils</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"></span></code></pre></div></li><li><p>Light 主题相当于之前的 default，把之前 default 的内容复制到 Light 里</p></li><li><p>根据前面写的注意事项，检查、修改、提取样式变量（注意命名、写好注释，以方便后面维护）</p></li><li><p>处理图片，可参考 2.3 图片静态资源处理</p></li></ol><p>之前没做换肤改造的：</p><p>步骤如上，涉及的文件建议文件对比看下</p><h2 id="_4-待处理-问题" tabindex="-1">4. 待处理 &amp; 问题 <a class="header-anchor" href="#_4-待处理-问题" aria-hidden="true">#</a></h2><ol><li><p>沉浸式 title 传值修改，应该要改 lib 库 ---- 已完成</p></li><li><p>我们目前暗黑的改造是不涉及组件库的，那么遇到组件库里没有用样式变量的地方，需要覆盖改背景色的，整理一份 ---- 已完成</p></li><li><p>weboa、手机网银（公式融合）暂时屏蔽暗黑 ---- 已完成</p></li></ol><h2 id="_5-附录" tabindex="-1">5. 附录： <a class="header-anchor" href="#_5-附录" aria-hidden="true">#</a></h2><ol><li><p><a href="https://docs.qq.com/sheet/DWnNOdk1waU1ZeGlm?tab=uc57cn" target="_blank" rel="noreferrer">UI 兆日科技原子样式换肤清单——暗黑模式</a></p></li><li><p><a href="https://bizmatedev.sinosun.com:17280/bizmate/static/notepad/pages/index.html" target="_blank" rel="noreferrer">记事本开发部署了，改动在 theme 分支上，可以参考</a></p></li></ol></div></div></main><!--[--><!--]--><footer class="VPDocFooter" data-v-2715c46c data-v-b6f746ca><div class="edit-info" data-v-b6f746ca><div class="edit-link" data-v-b6f746ca><a class="VPLink link edit-link-button" href="https://github.com/bayi-95/my-bolg/tree/master/docs/pages/javascript/暗黑模式前端修改方案.md" target="_blank" rel="noreferrer" data-v-b6f746ca data-v-7fdf1e32><!--[--><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="edit-link-icon" data-v-b6f746ca><path d="M18,23H4c-1.7,0-3-1.3-3-3V6c0-1.7,1.3-3,3-3h7c0.6,0,1,0.4,1,1s-0.4,1-1,1H4C3.4,5,3,5.4,3,6v14c0,0.6,0.4,1,1,1h14c0.6,0,1-0.4,1-1v-7c0-0.6,0.4-1,1-1s1,0.4,1,1v7C21,21.7,19.7,23,18,23z"></path><path d="M8,17c-0.3,0-0.5-0.1-0.7-0.3C7,16.5,6.9,16.1,7,15.8l1-4c0-0.2,0.1-0.3,0.3-0.5l9.5-9.5c1.2-1.2,3.2-1.2,4.4,0c1.2,1.2,1.2,3.2,0,4.4l-9.5,9.5c-0.1,0.1-0.3,0.2-0.5,0.3l-4,1C8.2,17,8.1,17,8,17zM9.9,12.5l-0.5,2.1l2.1-0.5l9.3-9.3c0.4-0.4,0.4-1.1,0-1.6c-0.4-0.4-1.2-0.4-1.6,0l0,0L9.9,12.5z M18.5,2.5L18.5,2.5L18.5,2.5z"></path></svg> Edit this page<!--]--><!----></a></div><div class="last-updated" data-v-b6f746ca><p class="VPLastUpdated" data-v-b6f746ca data-v-4a6113bb>Last updated: <time datetime="2023-03-29T09:22:44.000Z" data-v-4a6113bb></time></p></div></div><!----></footer><!--[--><!--]--></div></div></div></div></div><footer class="VPFooter" data-v-bcf58b99 data-v-648d7a08><div class="container" data-v-648d7a08><p class="message" data-v-648d7a08>部分文章收录于网络，转载请署名出处 | 联系博主可以发送邮件至 <a href="mailto:necro.vice@yahoo.com">necro.vice@yahoo.com</a></p><p class="copyright" data-v-648d7a08>Copyright © 2020-present</p></div></footer><!--[--><!--]--></div></div>
    <script>__VP_HASH_MAP__ = JSON.parse("{\"pages_javascript_source.md\":\"d80352b7\",\"pages_list_index.md\":\"c8c09e37\",\"pages_javascript_code.md\":\"b988f480\",\"index.md\":\"1ec62178\",\"pages_javascript_暗黑模式前端修改方案.md\":\"6cdec8ec\",\"pages_python_code.md\":\"ed62e3b2\",\"pages_python_source.md\":\"4b129630\",\"pages_react-native_code.md\":\"02e43813\",\"pages_react-native_index.md\":\"1ef81306\",\"pages_react-native_source.md\":\"d9eab48b\",\"pages_react_code.md\":\"94a0feee\",\"pages_react_source.md\":\"56f349ec\",\"pages_vue_code.md\":\"73247b19\",\"pages_logs_index.md\":\"35beb15f\",\"pages_vue_source.md\":\"1b064215\",\"pages_idea_思维模型.md\":\"50ebcb7f\",\"pages_idea_爱和治愈自己.md\":\"fad6366d\"}")</script>
    <script type="module" async src="/assets/app.4866b9fc.js"></script>
    
  </body>
</html>